package com.feature50.makeover.wii;

import wiiusej.WiiUseApiManager;
import wiiusej.Wiimote;
import wiiusej.values.GForce;
import wiiusej.values.IRSource;
import wiiusej.wiiuseapievents.*;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class WiiDartTracker {
    private Wiimote mote;
    private WiimoteListener listener;

    private Set<DartListener> dartFiredListeners = new HashSet<DartListener>();

    private float mx = 0.5f;
    private float my = 0.5f;

    private float gx = 0;
    private float gy = 0;
    private float gz = 0;

    private boolean coordinatesLocked = false;
    private long lockTime = -1;
    private boolean dartFired = false;

    public boolean activeWiimote() {
        Wiimote[] motes = WiiUseApiManager.getWiimotes(1, true);
        if (motes.length == 0) return false;

        mote = motes[0];

        mote.activateIRTRacking();
        mote.activateMotionSensing();

        listener = new WiimoteListener() {
            public void onButtonsEvent(ButtonsEvent event) {
                if (event.isButtonAHeld()) {
                    coordinatesLocked = true;

//                    if (lockTime == -1) lockTime = System.currentTimeMillis();
//
//                    if (System.currentTimeMillis() - lockTime > 2000) {
//                        fireDart();
//                        dartFired = true;
//                    }
                } else if (event.isButtonBHeld()) {
                    coordinatesLocked = false;
                    lockTime = -1;
                    dartFired = false;
                    gx = 0;
                    gy = 0;
                    gz = 0;
                } else {
                    if (coordinatesLocked) {
                        fireDart();
                        dartFired = true;
                        return;
                    }
                }
            }

            public void onIrEvent(IREvent event) {
                if (coordinatesLocked) return;

                IRSource[] points = event.getIRPoints();
                if ((points == null) || (points.length == 0)) {
                    return;
                }

                IRSource source = points[0];
                mx = (float) source.getX() / 1023f;
                my = (float) source.getY() / 767f;
            }

            public void onMotionSensingEvent(MotionSensingEvent event) {
                if (coordinatesLocked) {
                    GForce gf = event.getGforce();
                    if (gf == null) return;

                    gx = Math.max(Math.abs(gf.getX()), gx);
                    gy = Math.max(Math.abs(gf.getY()), gy);
                    gz = Math.max(Math.abs(gf.getZ()), gz);
                }
            }

            public void onStatusEvent(StatusEvent event) {}

            public void onDisconnectionEvent(DisconnectionEvent event) {}
        };
        mote.addWiiMoteEventListeners(listener);

        return true;
    }

    private void fireDart() {
        for (Iterator<DartListener> iterator = dartFiredListeners.iterator(); iterator.hasNext();) {
            DartListener dl = iterator.next();
            dl.dartFired(1.0f, 0.5f, 0.5f);
        }
    }

    public boolean isFired() {
        return dartFired;
    }

    public float getDartX() {
        return mx;
    }

    public float getDartY() {
        return my;
    }

    public float getGx() {
        return gx;
    }

    public float getGy() {
        return gy;
    }

    public float getGz() {
        return gz;
    }

    public void addDartListener(DartListener listener) {
        dartFiredListeners.add(listener);
    }

    public void removeDartListener(DartListener listener) {
        dartFiredListeners.remove(listener);
    }

    public void deactivateWiimote() {
        if (mote == null) return;

        mote.deactivateIRTRacking();
        mote.deactivateMotionSensing();
        mote.removeWiiMoteEventListeners(listener);
    }
}
